package org.ysling.litemall.admin.web;
// Copyright (c) [ysling] [927069313@qq.com]
// [litemall-plus] is licensed under Mulan PSL v2.
// You can use this software according to the terms and conditions of the Mulan PSL v2.
// You may obtain a copy of Mulan PSL v2 at:
//             http://license.coscl.org.cn/MulanPSL2
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
// See the Mulan PSL v2 for more details.

import com.github.binarywang.wxpay.bean.result.WxPayRefundResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.ysling.litemall.admin.annotation.RequiresPermissionsDesc;
import org.ysling.litemall.core.service.ActionLogService;
import org.ysling.litemall.core.service.OrderCoreService;
import org.ysling.litemall.core.utils.JacksonUtil;
import org.ysling.litemall.core.utils.response.ResponseUtil;
import org.ysling.litemall.core.validator.Order;
import org.ysling.litemall.core.validator.Sort;
import org.ysling.litemall.core.weixin.service.WeixinPayCoreService;
import org.ysling.litemall.core.weixin.service.SubscribeMessageService;
import org.ysling.litemall.db.domain.LitemallAftersale;
import org.ysling.litemall.db.domain.LitemallOrder;
import org.ysling.litemall.db.domain.LitemallUser;
import org.ysling.litemall.db.service.*;
import org.ysling.litemall.db.constant.AftersaleConstant;
import org.ysling.litemall.db.constant.OrderConstant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.time.LocalDateTime;
import java.util.List;

@Slf4j
@RestController
@RequestMapping("/admin/aftersale")
@Validated
public class AdminAftersaleController {

    @Autowired
    private SubscribeMessageService subscribeMessageService;
    @Autowired
    private ActionLogService logService;
    @Autowired
    private LitemallAftersaleService aftersaleService;
    @Autowired
    private LitemallOrderService orderService;
    @Autowired
    private LitemallUserService userService;
    @Autowired
    private OrderCoreService orderCoreService;
    @Autowired
    private WeixinPayCoreService payCoreService;


    @RequiresPermissions("admin:aftersale:list")
    @RequiresPermissionsDesc(menu = {"商场管理", "售后管理"}, button = "查询")
    @GetMapping("/list")
    public Object list(Integer orderId, String aftersaleSn, Short status,
                       @RequestParam(defaultValue = "1") Integer page,
                       @RequestParam(defaultValue = "10") Integer limit,
                       @Sort @RequestParam(defaultValue = "add_time") String sort,
                       @Order @RequestParam(defaultValue = "desc") String order) {
        List<LitemallAftersale> aftersaleList = aftersaleService.querySelective(orderId, aftersaleSn, status, page, limit, sort, order);
        return ResponseUtil.okList(aftersaleList);
    }

    @RequiresPermissions("admin:aftersale:recept")
    @RequiresPermissionsDesc(menu = {"商场管理", "售后管理"}, button = "审核通过")
    @PostMapping("/recept")
    public Object recept(@RequestBody LitemallAftersale aftersale) {

        LitemallAftersale aftersaleOne = aftersaleService.findById(aftersale.getId());
        if(aftersaleOne == null){
            return ResponseUtil.fail("售后不存在");
        }

        if(!aftersaleOne.getStatus().equals(AftersaleConstant.STATUS_REQUEST)){
            return ResponseUtil.fail("售后不能进行审核通过操作");
        }

        LitemallOrder order = orderService.findById(aftersale.getUserId(), aftersale.getOrderId());
        if (order == null) {
            return ResponseUtil.badArgument();
        }

        aftersaleOne.setStatus(AftersaleConstant.STATUS_RECEPT);
        aftersaleOne.setHandleTime(LocalDateTime.now());
        if (aftersaleService.updateVersionSelective(aftersaleOne) == 0) {
            return ResponseUtil.fail("售后修改失败");
        }

        //订单也要更新售后状态
        order.setAftersaleStatus(AftersaleConstant.STATUS_RECEPT);
        order.setOrderStatus(OrderConstant.STATUS_DISPOSE_AFTERSALE);
        if (orderService.updateVersionSelective(order) == 0) {
            throw new RuntimeException("更新数据已失效");
        }

        return ResponseUtil.ok();
    }

    @RequiresPermissions("admin:aftersale:batch-recept")
    @RequiresPermissionsDesc(menu = {"商场管理", "售后管理"}, button = "批量通过")
    @PostMapping("/batch-recept")
    public Object batchRecept(@RequestBody String body) {
        List<Integer> ids = JacksonUtil.parseIntegerList(body, "ids");
        if (ids == null) {
            return ResponseUtil.badArgument();
        }
        // NOTE
        // 批量操作中，如果一部分数据项失败，应该如何处理
        // 这里采用忽略失败，继续处理其他项。
        // 当然开发者可以采取其他处理方式，具体情况具体分析，例如利用事务回滚所有操作然后返回用户失败信息
        for(Integer id : ids) {
            LitemallAftersale aftersale = aftersaleService.findById(id);
            if(aftersale == null){
                continue;
            }

            if(!aftersale.getStatus().equals(AftersaleConstant.STATUS_REQUEST)){
                continue;
            }

            LitemallOrder order = orderService.findById(aftersale.getUserId(), aftersale.getOrderId());
            if (order == null) {
                return ResponseUtil.badArgument();
            }

            aftersale.setStatus(AftersaleConstant.STATUS_RECEPT);
            aftersale.setHandleTime(LocalDateTime.now());
            if (aftersaleService.updateVersionSelective(aftersale) == 0) {
                return ResponseUtil.fail( "售后更新失败");
            }

            //订单也要更新售后状态
            order.setAftersaleStatus(AftersaleConstant.STATUS_RECEPT);
            order.setOrderStatus(OrderConstant.STATUS_DISPOSE_AFTERSALE);
            if (orderService.updateVersionSelective(order) == 0) {
                throw new RuntimeException("更新数据已失效");
            }
        }
        return ResponseUtil.ok();
    }

    @RequiresPermissions("admin:aftersale:reject")
    @RequiresPermissionsDesc(menu = {"商场管理", "售后管理"}, button = "审核拒绝")
    @PostMapping("/reject")
    public Object reject(@RequestBody LitemallAftersale aftersale) {
        LitemallAftersale aftersaleOne = aftersaleService.findById(aftersale.getId());
        if(aftersaleOne == null){
            return ResponseUtil.badArgumentValue();
        }

        if(!aftersaleOne.getStatus().equals(AftersaleConstant.STATUS_REQUEST)){
            return ResponseUtil.fail( "售后不能进行审核拒绝操作");
        }

        LitemallOrder order = orderService.findById(aftersale.getUserId(), aftersale.getOrderId());
        if (order == null) {
            return ResponseUtil.badArgument();
        }

        aftersaleOne.setStatus(AftersaleConstant.STATUS_REJECT);
        aftersaleOne.setHandleTime(LocalDateTime.now());
        if (aftersaleService.updateVersionSelective(aftersaleOne) == 0) {
            return ResponseUtil.fail( "售后更新失败");
        }

        //订单也要更新售后状态
        order.setAftersaleStatus(AftersaleConstant.STATUS_REJECT);
        order.setOrderStatus(OrderConstant.STATUS_REJECT_AFTERSALE);
        if (orderService.updateVersionSelective(order) == 0){
           throw new RuntimeException("更新数据失效");
        }
        return ResponseUtil.ok();
    }

    @RequiresPermissions("admin:aftersale:batch-reject")
    @RequiresPermissionsDesc(menu = {"商场管理", "售后管理"}, button = "批量拒绝")
    @PostMapping("/batch-reject")
    public Object batchReject(@RequestBody String body) {
        List<Integer> ids = JacksonUtil.parseIntegerList(body, "ids");
        for(Integer id : ids) {

            LitemallAftersale aftersale = aftersaleService.findById(id);
            if(aftersale == null){
                continue;
            }

            if(!aftersale.getStatus().equals(AftersaleConstant.STATUS_REQUEST)){
                continue;
            }

            LitemallOrder order = orderService.findById(aftersale.getUserId(), aftersale.getOrderId());
            if (order == null) {
                return ResponseUtil.badArgument();
            }

            aftersale.setStatus(AftersaleConstant.STATUS_REJECT);
            aftersale.setHandleTime(LocalDateTime.now());
            if (aftersaleService.updateVersionSelective(aftersale) == 0) {
                return ResponseUtil.fail("售后更新失败");
            }

            //订单也要更新售后状态
            order.setAftersaleStatus(AftersaleConstant.STATUS_REJECT);
            order.setOrderStatus(OrderConstant.STATUS_REJECT_AFTERSALE);
            if (orderService.updateVersionSelective(order) == 0){
                throw new RuntimeException("更新数据失效");
            }
        }
        return ResponseUtil.ok();
    }

    @RequiresPermissions("admin:aftersale:refund")
    @RequiresPermissionsDesc(menu = {"商场管理", "售后管理"}, button = "退款")
    @PostMapping("/refund")
    public Object refund(@RequestBody LitemallAftersale aftersale) {
        LitemallAftersale aftersaleOne = aftersaleService.findById(aftersale.getId());
        if(aftersaleOne == null){
            return ResponseUtil.badArgumentValue();
        }

        if(!aftersaleOne.getStatus().equals(AftersaleConstant.STATUS_RECEPT)){
            return ResponseUtil.fail( "售后不能进行退款操作");
        }

        Integer orderId = aftersaleOne.getOrderId();
        LitemallOrder order = orderService.findById(orderId);
        if (order == null) {
            return ResponseUtil.badArgument();
        }

        // 微信退款
        WxPayRefundResult refundResult = payCoreService.wxPayAftersaleRefund(order , aftersaleOne);

        //修改售后信息
        aftersaleOne.setStatus(AftersaleConstant.STATUS_REFUND);
        aftersaleOne.setHandleTime(LocalDateTime.now());
        if (aftersaleService.updateVersionSelective(aftersaleOne) == 0) {
            return ResponseUtil.fail( "售后更新失败");
        }

        // 记录订单退款相关信息
        order.setRefundType("微信退款接口");
        order.setRefundTime(LocalDateTime.now());
        order.setRefundAmount(order.getActualPrice());
        order.setRefundContent(refundResult.getRefundId());
        order.setAftersaleStatus(AftersaleConstant.STATUS_REFUND);
        //修改订单状态
        order.setOrderStatus(OrderConstant.STATUS_FINISH_AFTERSALE);
        if (orderService.updateVersionSelective(order) == 0) {
            throw new RuntimeException("更新数据已失效");
        }

        // 返还订单
        orderCoreService.orderRelease(order);

        //订单退款订阅通知
        LitemallUser user = userService.findById(order.getUserId());
        subscribeMessageService.refundSubscribe(user.getWeixinOpenid(),order);

        //记录操作日志
        logService.logOrderSucceed("退款", "订单编号 " + order.getOrderSn());
        return ResponseUtil.ok();
    }
}
